﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using InHD.model;
using System.Reflection;
using System.Data;
using InHD.utilities;

namespace InHD.dataaccess
{
    class CustomerRepository
    {
        #region Fields
        List<Customer> _customers;
        //For DB Utils
        private DBUltils _db;
        string[] _paramName;
        string[] _value;
        DBUltils.ParamType[] _paramType;
        #endregion // Fields

        #region Constructor

        /// <summary>
        /// Creates a new repository of Customers.
        /// </summary>
        public CustomerRepository()
        {
            _customers = new List<Customer>();
            this._db = new DBUltils();
            if (!_db.connectDB(Constants.Security.DefaultDBUser, Constants.Security.DefaultDBPassword))
                throw new ArgumentNullException(Constants.Messages.CannotConnectDB);
        }

        #endregion // Constructor

        #region Public Interface

        public event EventHandler<CustomerAddedEventArgs> CustomerAdded;

        public string AddCustomer(Customer customer)
        {
            try
            {
                if (customer == null)
                    throw new ArgumentNullException("customer");
                for (int i = 0; i < this._customers.Count; i++)
                {
                    if (this._customers[i].CustomerCode.Equals(customer.CustomerCode))
                    {
                        return "DuplicateCode";
                    }
                }

                customer.CustomerUNK = "Cus-" + Guid.NewGuid().ToString();

                //// Add new customer into database
                if (_db == null)
                    throw new ArgumentNullException(Constants.Messages.DBNotInitialized);
                if (customer.CustomerUNK == null)
                    throw new ArgumentNullException("Null unique key");
                _paramName = new string[]{"@customerUNK",
                                      "@customerCode",
                                      "@firstname",
                                      "@lastname",
                                      "@address",
                                      "@email",
                                      "@phone",
                                      "@fax",
                                      "@totalBought",
                                      "@company",
                                      "@position",
                                      "@lastAccess",
                                        };
                _paramType = new DBUltils.ParamType[]{
                                                    DBUltils.ParamType.Str,
                                                    DBUltils.ParamType.Str,
                                                    DBUltils.ParamType.NStr,
                                                    DBUltils.ParamType.NStr,
                                                    DBUltils.ParamType.LNStr,
                                                    DBUltils.ParamType.Str,
                                                    DBUltils.ParamType.Str,
                                                    DBUltils.ParamType.Str,
                                                    DBUltils.ParamType.Real,
                                                    DBUltils.ParamType.NStr,
                                                    DBUltils.ParamType.NStr,
                                                    DBUltils.ParamType.DateTime,
                                                    };
                _value = new string[]{
                                    customer.CustomerUNK,
                                    customer.CustomerCode,
                                    customer.FirstName,
                                    customer.LastName,
                                    (customer.Address == null) ? string.Empty : customer.Address,
                                    (customer.Email == null) ? string.Empty : customer.Email,
                                    (customer.Phone == null) ? string.Empty : customer.Phone,
                                    (customer.Fax == null) ? string.Empty : customer.Fax,
                                    Convert.ToString(customer.TotalBought),
                                    (customer.Company == null) ? string.Empty : customer.Company,
                                    (customer.Position == null) ? string.Empty : customer.Position,
                                    System.DateTime.Now.ToString()
                                    };

                _db.queryDB("AddCustomer", _paramName, _paramType, _value, DBUltils.QueryType.Insert);
                _customers.Add(customer);

                if (this.CustomerAdded != null)
                    this.CustomerAdded(this, new CustomerAddedEventArgs(customer));
            }
            catch (Exception e)
            {
                Logger.RecordMessage(e, MessageType.Error);
                return e.Message;
            }
            //System.Windows.MessageBox.Show("Add customer successfully!!!");
            return string.Empty;
        }

        public string EditCustomer(Customer customer)
        {
            try
            {
                if (customer == null)
                    throw new ArgumentNullException("customer");

                //// edit existing product which have customerUNK  == customer.customerUNK
                for (int i = 0; i < this._customers.Count; i++)
                {
                    if (this._customers[i].CustomerUNK.Equals(customer.CustomerUNK))
                    {
                        for (int j = 0; j < this._customers.Count; j++)
                        {
                            if ((i!=j) && this._customers[j].CustomerCode.Equals(customer.CustomerCode))
                            {
                                return "DuplicateCode";
                            }
                        }
                        this._customers[i] = customer;
                        if (_db == null)
                            throw new ArgumentNullException(Constants.Messages.DBNotInitialized);
                        _paramName = new string[]{"@customerUNK",
                                      "@customerCode",
                                      "@firstname",
                                      "@lastname",
                                      "@address",
                                      "@email",
                                      "@phone",
                                      "@fax",
                                      "@totalBought",
                                      "@company",
                                      "@position",
                                      "@lastAccess",
                                        };
                        _paramType = new DBUltils.ParamType[]{
                                                    DBUltils.ParamType.Str,
                                                    DBUltils.ParamType.Str,
                                                    DBUltils.ParamType.NStr,
                                                    DBUltils.ParamType.NStr,
                                                    DBUltils.ParamType.LNStr,
                                                    DBUltils.ParamType.Str,
                                                    DBUltils.ParamType.Str,
                                                    DBUltils.ParamType.Str,
                                                    DBUltils.ParamType.Real,
                                                    DBUltils.ParamType.NStr,
                                                    DBUltils.ParamType.NStr,
                                                    DBUltils.ParamType.DateTime,
                                                    };
                        _value = new string[]{
                                    customer.CustomerUNK,
                                    customer.CustomerCode,
                                    customer.FirstName,
                                    customer.LastName,
                                    (customer.Address == null) ? string.Empty : customer.Address,
                                    (customer.Email == null) ? string.Empty : customer.Email,
                                    (customer.Phone == null) ? string.Empty : customer.Phone,
                                    (customer.Fax == null) ? string.Empty : customer.Fax,
                                    Convert.ToString(customer.TotalBought),
                                    (customer.Company == null) ? string.Empty : customer.Company,
                                    (customer.Position == null) ? string.Empty : customer.Position,
                                    System.DateTime.Now.ToString()
                                    };

                        _db.queryDB("UpdateCustomer", _paramName, _paramType, _value, DBUltils.QueryType.Update);
                        break;
                    }
                }
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
            //System.Windows.MessageBox.Show("Edit customer successfully!!!");
            return string.Empty;
        }

        public string DeleteCustomer(string customerUNK)
        {
            bool found = false;
            foreach (Customer cus in this._customers)
            {
                if (cus.CustomerUNK.Equals(customerUNK))
                {
                    this._customers.Remove(cus);
                    found = true;
                    break;
                }
            }
            if (!found)
                return "UNK is not exist";
            try
            {
                if (_db == null)
                    throw new ArgumentNullException(Constants.Messages.DBNotInitialized);
                if (customerUNK == null)
                    throw new ArgumentNullException("Null Unique key");
                _paramName = new string[] { "@cusUNK" };
                _paramType = new DBUltils.ParamType[] { DBUltils.ParamType.Str };
                _value = new string[] { customerUNK };

                _db.queryDB("DeleteCustomer", _paramName, _paramType, _value, DBUltils.QueryType.Delete);
            }
            catch (Exception e)
            {
                Logger.RecordMessage(e, MessageType.Error);
                return e.Message;
            }
            //System.Windows.MessageBox.Show("Delete Customer successfully!!!");
            return string.Empty;
        }

        public List<Customer> GetCustomers()
        {
            return this._customers;
        }

        public List<Customer> GetProductsWthSearchCriteria(string property, string criteria)
        {
            if (string.IsNullOrEmpty(criteria))
            {
                criteria = string.Empty;
            }
            List<Customer> tmpList = new List<Customer>();
            foreach (Customer pro in this._customers)
            {
                Type t = pro.GetType();
                PropertyInfo p = t.GetProperty(property);
                string valueOfProperty = (string)p.GetValue(pro, null);
                if (valueOfProperty.ToUpper().Contains(criteria.ToUpper()))
                {
                    tmpList.Add(pro);
                }
            }

            return tmpList;
        }

        public string LoadAllCustomers()
        {
            try
            {
                if (_db == null)
                    throw new ArgumentNullException(Constants.Messages.DBNotInitialized);
                _paramName = new string[] { };
                _paramType = new DBUltils.ParamType[] { };
                _value = new string[] { };
                DataSet ds = _db.queryDB("GetAllCustomer", _paramName, _paramType, _value, DBUltils.QueryType.Select);

                foreach (DataRow r in ds.Tables[0].Rows)
                {
                    Customer cus = Customer.CreateCustomerInfo(Convert.ToString(r["customerCode"]),
                                                                Convert.ToString(r["firstName"]),
                                                                Convert.ToString(r["lastName"]),
                                                                Convert.ToString(r["company"]),
                                                                Convert.ToString(r["position"]),
                                                                Convert.ToString(r["phone"]),
                                                                Convert.ToString(r["fax"]),
                                                                Convert.ToString(r["email"]),
                                                                Convert.ToString(r["address"]),
                                                                Convert.ToString(r["customerUNK"]),
                                                                Convert.ToDouble(r["totalBoughtAmt"]),
                                                                Convert.ToDateTime(r["lastAccess"])
                                                                );
                    this._customers.Add(cus);
                }
            }
            catch (Exception e)
            {
                Logger.RecordMessage(e, MessageType.Error);
                return e.Message;
            }
            return string.Empty;
        }
        #endregion // Public Interface       
    
        public string DeleteCustomer(Customer customer)
        {
            return string.Empty;
        }
    }
}
